﻿#undef TRACE
using System;
using System.Diagnostics;
using System.Web;
using ErrorDumper.Filtering;
using ErrorDumper.Processing;
using ErrorDumper.PropertyExtracting;
using ErrorDumper.Web.Filters;
using ErrorDumper.Web.Processors;
using ErrorDumper.Web.PropertyExtractors;
using ErrorDumper.Writing;
using Microsoft.Web.Infrastructure.DynamicModuleHelper;

namespace ErrorDumper.Web {
    public class ErrorDumperHttpModule : IHttpModule {
        private HttpApplication _application;

        public void Init(HttpApplication application) {
            Trace.TraceInformation("ErrorDumperHttpModule.Init: begin");
            if (application == null)
                throw new ArgumentNullException("application");

            _application = application;

            // PropertyExtractors
            ExceptionPropertyExtractors.RegisterTypeExtractor<HttpException, HttpExceptionPropertyBinder>();
            ExceptionPropertyExtractors.RegisterTypeExtractor<HttpContext, HttpContextPropertyBinder>();
            ExceptionPropertyExtractors.RegisterTypeExtractor<HttpContextBase, HttpContextPropertyBinder>();

            // Processors
            ExceptionProcessors.RegisterProcessor<HttpContextProcessor>();

            // DataSource
            ExceptionDataSource.Current = new WebExceptionDataSource();

            // Writers
            ExceptionWriters.RegisterWriter<DirectoryExceptionWriter>();

            // Ignore 404 HttpException
            if (!ExceptionFilters.IsRegisteredTypeFilter<HttpException>(i => i is HttpExceptionFilter && ((HttpExceptionFilter)i).HttpCode == 404 && ((HttpExceptionFilter)i).Level == ExceptionHandlingLevel.Ignore))
                ExceptionFilters.RegisterTypeFilter<HttpException>(new HttpExceptionFilter(404, ExceptionHandlingLevel.Ignore));

            application.Error += application_Error;
            Trace.TraceInformation("ErrorDumperHttpModule.Init: end");
        }

        void application_Error(object sender, EventArgs e) {
            var error = _application.Server.GetLastError();
            Trace.TraceError("ErrorDumperHttpModule.Error: {0}", error != null ? error.Message : null);
            if (error != null)
                ExceptionHandler.HandleExceptionSafely(error);
        }

        private static bool _setupWasCalled;

        public static void SetUp() {
            Trace.TraceError("ErrorDumperHttpModule.SetUp: begin");
            if (_setupWasCalled)
                return;
            _setupWasCalled = true;
            DynamicModuleUtility.RegisterModule(typeof(ErrorDumperHttpModule));
            Trace.TraceError("ErrorDumperHttpModule.SetUp: end");
        }

        public void Dispose() {
            Trace.TraceError("ErrorDumperHttpModule.Dispose");
        }
    }
}